package com.scarecrow.olga.game.component {
	import com.scarecrow.olga.error.AbstractMethodException;
	import com.scarecrow.olga.game.object.GameObject;
	import com.scarecrow.olga.util.logging.Logger;
	import flash.utils.getDefinitionByName;
	import flash.utils.getQualifiedClassName;
	
	/**
	 * ...
	 * @author Santiago.J.Elizalde
	 */
	public class GameComponent {
		
		private var _type:Class;
		private var _owner:GameObject;
		
		public function GameComponent() {
			this._type = getDefinitionByName(getQualifiedClassName(this)) as Class;
		}
		
		
		/**
		 * The GameComponent's owner, a GameObject that contains the instance of
		 * this component among other components.
		 * 
		 * setting the owner to NULL will trigger a call to the GameComponent's 
		 * releaseGameObject() method.
		 * 
		 * @see releaseGameObject() method.
		 */
		public final function get owner():GameObject {
			return _owner;
		}
		
		public final function set owner(value:GameObject):void {
			if (value && _owner) {
				Logger.log("Attempted to set an owner of an already owned GameComponent.", Logger.LOG_LEVEL_WARN);
				return;
			}
			if (_owner && !value) {
				_owner = value;
				releaseGameObject();
			}
			if (value && !_owner) {
				_owner = value;
				initialize();
			}
		}
		
		/**
		 * The Class of this component, used as a key to register components in GameObjects
		 */
		public function get type():Class {
			return _type;
		}
		
		public function toString():String {
			return getQualifiedClassName(this);
		}
		
		/**
		 * This function should perform any logic needed to remove this gameComponent from its
		 * owning GameObject. These tasks could include from changing, adding or erasing properties
		 * from the _owner object to removing other components or even destroying the _owner.
		 */
		protected function releaseGameObject():void {
			throw new AbstractMethodException("releaseGameObject()", {atClass:type});
		}
		
		/**
		 * This function is called once the component's owner has been set,
		 * object initialization tasks that requiere the owning Game Object
		 * must be implemented here.
		 */
		protected function initialize():void {
			throw new AbstractMethodException("initialize()", {atClass:type});
		}
	}
}